package com.cvtt.common;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

import android.util.Log;

public class RC4 {
	
	private static RC4 mInstance = null;
	
	private SecretKey mSecKey;
	
	private Cipher mCipher;
	
    private final byte[] mState = new byte[256];
    
    public static synchronized RC4 getInstance() {
		if (mInstance == null) {
			mInstance = new RC4();
		}
		return mInstance;
	}
    
    public RC4() {
    	String strKey = "9cmk2T$g";
    	byte[] byteKey = strKey.getBytes();
    	mSecKey = new SecretKeySpec(byteKey, "RC4");
		try {
			mCipher = Cipher.getInstance("RC4");
		} catch(Exception e){
			e.printStackTrace();
		}
    }
    
    public RC4(final byte[] key) {
    	byte[] T = new byte[256];
        int keylen;
    	if (key.length < 1 || key.length > 256) {
            throw new IllegalArgumentException(
                    "key must be between 1 and 256 bytes");
        } else {
            keylen = key.length;
            for (int i = 0; i < 256; i++) {
            	mState[i] = (byte) i;
                T[i] = key[i % keylen];
            }
            int j = 0;
            for (int i = 0; i < 256; i++) {
                j = (j + mState[i] + T[i]) & 0xFF;
                mState[i] ^= mState[j];
                mState[j] ^= mState[i];
                mState[i] ^= mState[j];
            }
        }
    }
    
    public static void printHexString( byte[] b) {  
		   for (int i = 0; i < b.length; i++) { 
		     String hex = Integer.toHexString(b[i] & 0xFF); 
		     if (hex.length() == 1) { 
		       hex = '0' + hex; 
		     } 
		     Log.v("Crypt",hex.toUpperCase() ); 
		   } 

		}

    public byte[] doCrypt(byte[] rawData) {
    	
    	byte[] rc4Data = new byte[rawData.length];
    	
    	try {
			mCipher.init(Cipher.ENCRYPT_MODE, mSecKey);
			rc4Data =  mCipher.doFinal(rawData);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
    	
        //printHexString(rc4Data);
        
        return rc4Data;
    }
    
    public void doCrypt(byte[] rawData,int pos,int len) {
    	
    	try {
			mCipher.init(Cipher.ENCRYPT_MODE, mSecKey);
			//byte[] cryptByte = mCipher.doFinal(rawData, pos, len);
			mCipher.doFinal(rawData, pos, len, rawData, pos);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
    }
}

